package com.yuanxin.screencapture;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.Log;
import android.widget.Toast;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.Permission;

import org.w3c.dom.Text;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;


/**
 * <p>文件描述：<p>
 * <p>作者：mike<p>
 * <p>创建时间：2018/9/4<p>
 * <p>更改时间：2018/9/4<p>
 */
public class ScreenCaptureModule extends ReactContextBaseJavaModule implements LifecycleEventListener {

    private static final String MODULE_NAME = "ScreenCapture";

    ScreenShotListenManager manager;

    private ReactApplicationContext context;
    private boolean isFirst=true;


    public ScreenCaptureModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.context = reactContext;
        reactContext.addLifecycleEventListener(this);

    }

    @Override
    public String getName() {
        return MODULE_NAME;
    }

    //水印参数
    private String text = "";
    private int textSize = 14;
    private String color = "#993b3b3b";
    private int textSpacing = 7; // 文字间距 单位dp
    private int horizontalSpacing = -1; // 横向间距
    private int verticalSpacing = -1; // 竖向间距

    @ReactMethod
    public void setWatermarkParams(ReadableMap map) {
        if (map == null)
            return;
        Log.i(MODULE_NAME, map.toString());
        if (map.hasKey("text")) {
            this.text = map.getString("text");
        }
        if (map.hasKey("textSize")) {
            this.textSize = map.getInt("textSize");
        }
        if (map.hasKey("color")) {
            this.color = map.getString("color");
        }
        if (map.hasKey("horizontalSpacing")) {
            this.horizontalSpacing = map.getInt("horizontalSpacing");
        }
        if (map.hasKey("verticalSpacing")) {
            this.verticalSpacing = map.getInt("verticalSpacing");
        }
        if (map.hasKey("textSpacing")) {
            this.textSpacing = map.getInt("textSpacing");
        }

    }

    @ReactMethod
    public void startListener(final Promise promise) {
        AndPermission.with(getCurrentActivity())
                .permission(Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE)
                .onGranted(new Action() {
                    @Override
                    public void onAction(List<String> permissions) {
                        context.getCurrentActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                manager.startListen();
                                promise.resolve("success");
                            }
                        });
                    }
                })
                .onDenied(new Action() {
                    @Override
                    public void onAction(List<String> permissions) {
                        promise.reject("error", "请赋予权限");
                    }
                }).start();
    }

    @ReactMethod
    public void stopListener() {
        context.getCurrentActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                manager.stopListen();
            }
        });
    }

    @Override
    public void onHostResume() {
        manager = ScreenShotListenManager.newInstance(context.getApplicationContext());
        manager.setListener(
                new ScreenShotListenManager.OnScreenShotListener() {
                    public void onShot(String imagePath) {
                        // do something
                        Log.d(MODULE_NAME, imagePath);
                        if (context != null && context.hasActiveCatalystInstance()) {
                            WritableMap map = Arguments.createMap();
                            map.putString("imagePath", imagePath);
                            context.getJSModule(RCTNativeAppEventEmitter.class)
                                    .emit("ScreenCapture", map);

                            if (null != text && !"".equals(text)) {
                                Bitmap bitmap;
                                try {
                                    bitmap = BitmapFactory.decodeStream(new FileInputStream(new File(imagePath)));
                                } catch (FileNotFoundException e) {
                                    e.printStackTrace();
                                    return;
                                }
                                if (bitmap != null) {
                                    Bitmap bitmap2 = addTextWatermark(bitmap);
                                    save(bitmap2, imagePath, Bitmap.CompressFormat.JPEG, true);
                                }

                            }


                        }
                    }
                }
        );
        if(isFirst) {
            AndPermission.with(getCurrentActivity())
                    .permission(Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE)
                    .onGranted(new Action() {
                        @Override
                        public void onAction(List<String> permissions) {
                            manager.startListen();
                        }
                    })
                    .onDenied(new Action() {
                        @Override
                        public void onAction(List<String> permissions) {
                            //Log.e(getName(), "permissions=" + permissions.size());
                            isFirst = false;
                        }
                    }).start();
        }
    }

    @Override
    public void onHostPause() {
        manager.stopListen();
    }

    @Override
    public void onHostDestroy() {
        if (manager != null)
            manager.stopListen();
    }


    /**
     * 给一张Bitmap添加水印文字。
     *
     * @param src 源图片
     * @return 已经添加水印后的Bitmap。
     */
    public Bitmap addTextWatermark(Bitmap src) {
        if (isEmptyBitmap(src))
            return null;
        Bitmap ret = src.copy(src.getConfig(), true);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Canvas canvas = new Canvas(ret);
        canvas.rotate(-45);
        paint.setColor(Color.parseColor(color));
        paint.setTextSize(dip2px(getReactApplicationContext(), textSize));

        float strWidth = 0;
        //获取文字宽度，有换行符的情况下，需要分段测量
        for (String s : text.split("\n")) {
            float width = paint.measureText(s);
            if (width > strWidth)
                strWidth = width;
        }

        StaticLayout layout = new StaticLayout(text, new TextPaint(paint), (int) strWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0, false);

        int index = 0;
        for (int positionY = src.getHeight() / 10; positionY <= src.getHeight(); positionY += layout.getHeight() +(verticalSpacing == -1 ? layout.getHeight()  : dip2px(getReactApplicationContext(), verticalSpacing ))) {
            float fromX = -src.getWidth() - strWidth * 2 + (index++ % 2) * strWidth;
            for (float positionX = fromX; positionX < src.getWidth(); positionX += strWidth+(horizontalSpacing == -1 ? strWidth  : dip2px(getReactApplicationContext(), horizontalSpacing ))) {
                int spacing = 0;//间距
                for (String label : text.split("\n")) {
                    canvas.drawText(label, positionX, positionY + spacing, paint);
                    //13是基础行间距，否则会重合
                    spacing = spacing + dip2px(getReactApplicationContext(), 13) + dip2px(getReactApplicationContext(), textSpacing);
                }
            }
        }
        canvas.save();
        canvas.restore();
        if (!src.isRecycled())
            src.recycle();
        return ret;
    }


    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 保存图片到文件File。
     *
     * @param src       源图片
     * @param imagePath 要保存到的文件
     * @param format    格式
     * @param recycle   是否回收
     * @return true 成功 false 失败
     */
    public boolean save(Bitmap src, String imagePath, Bitmap.CompressFormat format, boolean recycle) {
        if (isEmptyBitmap(src))
            return false;
        if (imagePath == null || "".equals(imagePath)) {
            return false;
        }
        OutputStream os;
        boolean ret = false;
        File file = new File(imagePath);
        if (file.exists()) {
            file.delete();
        }
        try {
            file.createNewFile();
            os = new BufferedOutputStream(new FileOutputStream(file));
            ret = src.compress(format, 100, os);
            if (recycle && !src.isRecycled())
                src.recycle();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * Bitmap对象是否为空。
     */
    public boolean isEmptyBitmap(Bitmap src) {
        return src == null || src.getWidth() == 0 || src.getHeight() == 0;
    }
}
